Skip to content

Add test MT.1106 to verify Protected Actions Auth Contexts have CA policies#1356

Draft
Copilot wants to merge 20 commits intomainfrom
copilot/add-maester-test-conditional-access
Draft

Add test MT.1106 to verify Protected Actions Auth Contexts have CA policies#1356
Copilot wants to merge 20 commits intomainfrom
copilot/add-maester-test-conditional-access

Conversation

Copy link
Contributor

Copilot AI commented Dec 2, 2025

  • Explore repository structure and understand existing test patterns
  • Understand the issue: Create a test to ensure all Protected Actions Auth Contexts have a Conditional Access policy referenced
  • Create the PowerShell test function Test-MtCaAuthContextProtectedActionsExist.ps1
  • Create the markdown documentation for the test (.md file)
  • Add the test to the test file Test-ConditionalAccessBaseline.Tests.ps1
  • Create website documentation
  • Validate PowerShell syntax
  • Address review feedback:
    • Renamed test from MT.1090 to MT.1106 (MT.1090 is already taken)
    • Filter CA policies to only enabled policies
    • Check isEnabled flag for authentication context rules
    • Fix loop to iterate over $authContextsInProtectedActions to detect deleted contexts
    • Update example text to use "require authentication context" instead of "require MFA"
    • Use "referenced" instead of "enforced" in warning message for consistency
    • Add UTF-8 BOM encoding to all .ps1 files
    • Add function to module manifest FunctionsToExport
    • Fix Protected Actions detection using correct API endpoint (roleManagement/directory/resourceNamespaces)
    • Debug property structure - added enhanced logging to identify correct property names

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ons Auth Context validation

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 2, 2025

Deploying maester with  Cloudflare Pages  Cloudflare Pages

Latest commit: 1049fa3
Status:⚡️  Build in progress...

View logs

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copilot AI changed the title [WIP] Add Maester test for protected actions auth context Add test MT.1090 to verify Protected Actions Auth Contexts have CA policies Dec 2, 2025
Copilot AI requested a review from SamErde December 2, 2025 16:53
@SamErde SamErde requested a review from Copilot December 2, 2025 17:37
@SamErde SamErde added enhancement New feature or request help wanted Extra attention is needed maester-test Related to a Maester test work started entra Microsoft Entra labels Dec 2, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new validation test to ensure that protected actions using Authentication Contexts are actually enforced by Conditional Access policies, plus associated documentation and baseline test wiring.

  • Introduces Test-MtCaAuthContextProtectedActionsExist to detect Authentication Contexts used by Protected Actions but not referenced by any CA policy.
  • Wires the test into the Conditional Access baseline suite (MT.1090).
  • Adds user-facing documentation for the test and website page.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
website/docs/tests/maester/MT.1090.md New website doc explaining MT.1090 test purpose, remediation steps, and links.
tests/Maester/Entra/Test-ConditionalAccessBaseline.Tests.ps1 Adds the MT.1090 test case to the Entra Conditional Access baseline suite.
powershell/public/maester/entra/Test-MtCaAuthContextProtectedActionsExist.ps1 Implements the test logic to correlate protected actions’ Authentication Contexts with CA policies.
powershell/public/maester/entra/Test-MtCaAuthContextProtectedActionsExist.md Adds command documentation with remediation steps and related links.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

@SamErde SamErde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test ID 'MT.1090' is already taken. 'MT.1106' should be used for this test. References within this PR need to be changed accordingly.

…s, check isEnabled for rules, detect deleted contexts

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Dec 2, 2025

The test ID 'MT.1090' is already taken. 'MT.1106' should be used for this test. References within this PR need to be changed accordingly.

Renamed to MT.1106 in commit 550d061. Updated the website doc, test file reference, title, and slug accordingly.

Copilot AI changed the title Add test MT.1090 to verify Protected Actions Auth Contexts have CA policies Add test MT.1106 to verify Protected Actions Auth Contexts have CA policies Dec 2, 2025
Copilot AI requested a review from SamErde December 2, 2025 18:16
@SamErde SamErde marked this pull request as ready for review December 2, 2025 18:34
@SamErde SamErde assigned SamErde and unassigned SamErde and Copilot Feb 4, 2026
@SamErde
Copy link
Contributor

SamErde commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be missing.

…tionsToExport

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be missing.

Added Test-MtCaAuthContextProtectedActionsExist to the FunctionsToExport in Maester.psd1 in commit 534a4b7.

Copy link
Contributor

@SamErde SamErde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for other peer review and testing.

@SamErde SamErde self-requested a review February 4, 2026 17:47
@SamErde
Copy link
Contributor

SamErde commented Feb 4, 2026

@copilot, this test reports a pass status for my environment, with a result message that states, "No Authentication Contexts are configured for Protected Actions in this tenant."

This is not accurately checking configuration. I have 5 protected actions that have authentication contexts assigned to them.

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot, this test reports a pass status for my environment, with a result message that states, "No Authentication Contexts are configured for Protected Actions in this tenant."

This is not accu...

I've added verbose logging in commit 30abcb0 to help diagnose the issue. Could you run the test with -Verbose flag to see what's being detected?

Test-MtCaAuthContextProtectedActionsExist -Verbose

The verbose output will show:

  • How many PIM policy assignments are found
  • Each rule type and its properties being checked
  • Which authentication contexts are found in protected actions

This will help identify if the issue is with:

  1. The PIM policies not being retrieved
  2. The authentication context rules not matching the expected structure
  3. The claimValue property name or format being different

Please share the verbose output so I can adjust the logic accordingly.

@SamErde
Copy link
Contributor

SamErde commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be missing.

Added Test-MtCaAuthContextProtectedActionsExist to the FunctionsToExport in Maester.psd1 in commit 534a4b7.

Test-MtCaAuthContextProtectedActionsExist -Verbose
VERBOSE: Found 134 PIM policy assignments
VERBOSE: Total authentication contexts found in protected actions: 0
True

…nagement/directory/resourceNamespaces)

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be missi...

Fixed in commit ffd203d. The issue was using the wrong API endpoint. Protected Actions are accessed through roleManagement/directory/resourceNamespaces and then checking resourceActions for authenticationContextId properties, not through PIM role management policies.

The updated code now:

  1. Queries roleManagement/directory/resourceNamespaces to get all resource namespaces
  2. For each namespace, retrieves resourceActions
  3. Checks each action's authenticationContextId property to find Protected Actions with auth contexts

Please test again with -Verbose to verify it now correctly detects your 5 protected actions with authentication contexts.

@SamErde
Copy link
Contributor

SamErde commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be missi...

Fixed in commit ffd203d. The issue was using the wrong API endpoint. Protected Actions are accessed through roleManagement/directory/resourceNamespaces and then checking resourceActions for authenticationContextId properties, not through PIM role management policies.

The updated code now:

  1. Queries roleManagement/directory/resourceNamespaces to get all resource namespaces
  2. For each namespace, retrieves resourceActions
  3. Checks each action's authenticationContextId property to find Protected Actions with auth contexts

Please test again with -Verbose to verify it now correctly detects your 5 protected actions with authentication contexts.

Test-MtCaAuthContextProtectedActionsExist -Verbose
VERBOSE: Found 74 resource namespaces
VERBOSE: Total authentication contexts found in protected actions: 0
True

… property names

Co-authored-by: SamErde <20478745+SamErde@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be m...

I've added enhanced verbose logging in commit 1049fa3 to show the actual structure of resource actions. Please run with -Verbose again:

Test-MtCaAuthContextProtectedActionsExist -Verbose

The new logging will show:

  • Count of resource actions in each namespace
  • Sample JSON structure of the first few actions from the first 3 namespaces
  • This will reveal what properties are actually present on the actions

This will help identify the correct property name for the authentication context ID. The screenshot shows "c4" as the auth context ID, so we need to find which property contains that value.

@SamErde
Copy link
Contributor

SamErde commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to be m...

I've added enhanced verbose logging in commit 1049fa3 to show the actual structure of resource actions. Please run with -Verbose again:

Test-MtCaAuthContextProtectedActionsExist -Verbose

The new logging will show:

  • Count of resource actions in each namespace
  • Sample JSON structure of the first few actions from the first 3 namespaces
  • This will reveal what properties are actually present on the actions

This will help identify the correct property name for the authentication context ID. The screenshot shows "c4" as the auth context ID, so we need to find which property contains that value.

Test-MtCaAuthContextProtectedActionsExist -Verbose
VERBOSE: Found 74 resource namespaces
VERBOSE: Namespace 1/74 (microsoft.directory): Found 709 resource actions
VERBOSE: Sample action properties: {"actionVerb":null,"description":"Create and delete access reviews, and read and update all properties of access reviews in Microsoft Entra ID","id":"microsoft.directory-accessReviews-allProperties-allTasks","isPrivileged":false,"name":"microsoft.directory/accessReviews/allProperties/allTasks","resourceScopeId":null}
VERBOSE: Sample action properties: {"actionVerb":"GET","description":"Read all properties of access reviews","id":"microsoft.directory-accessReviews-allProperties-read-get","isPrivileged":false,"name":"microsoft.directory/accessReviews/allProperties/read","resourceScopeId":null}
VERBOSE: Sample action properties: {"actionVerb":null,"description":"Manage access reviews of application role assignments in Microsoft Entra ID","id":"microsoft.directory-accessReviews-definitions.applications-allProperties-allTasks","isPrivileged":false,"name":"microsoft.directory/accessReviews/definitions.applications/allProperties/allTasks","resourceScopeId":null}
VERBOSE: Namespace 2/74 (microsoft.aad.b2c): Found 1 resource actions
VERBOSE: Could not retrieve resource actions for namespace microsoft.aad.b2c: Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named 'IndexOf'.
VERBOSE: Namespace 3/74 (microsoft.aad.cloudAppSecurity): Found 1 resource actions
VERBOSE: Could not retrieve resource actions for namespace microsoft.aad.cloudAppSecurity: Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named 'IndexOf'.
VERBOSE: Namespace 4/74 (microsoft.aad.directorySync): Found 1 resource actions
VERBOSE: Namespace 5/74 (microsoft.aad.identityProtection): Found 1 resource actions
VERBOSE: Namespace 6/74 (microsoft.aad.privilegedIdentityManagement): Found 1 resource actions
VERBOSE: Namespace 7/74 (microsoft.aad.reports): Found 1 resource actions
VERBOSE: Namespace 8/74 (microsoft.agentRegistry): Found 2 resource actions
VERBOSE: Namespace 9/74 (microsoft.azure.advancedThreatProtection): Found 1 resource actions
VERBOSE: Namespace 10/74 (microsoft.azure.customSecurityAttributeDiagnosticSettings): Found 1 resource actions
VERBOSE: Namespace 11/74 (microsoft.azure.devOps): Found 1 resource actions
VERBOSE: Namespace 12/74 (microsoft.azure.informationProtection): Found 1 resource actions
VERBOSE: Namespace 13/74 (microsoft.azure.print): Found 6 resource actions
VERBOSE: Namespace 14/74 (microsoft.azure.serviceHealth): Found 1 resource actions
VERBOSE: Namespace 15/74 (microsoft.azure.supportTickets): Found 1 resource actions
VERBOSE: Namespace 16/74 (microsoft.backup): Found 17 resource actions
VERBOSE: Namespace 17/74 (microsoft.cloudPC): Found 2 resource actions
VERBOSE: Namespace 18/74 (microsoft.commerce.billing): Found 3 resource actions
VERBOSE: Namespace 19/74 (microsoft.commerce.tenantRelationships): Found 1 resource actions
VERBOSE: Namespace 20/74 (microsoft.commerce.volumeLicenseServiceCenter): Found 1 resource actions
VERBOSE: Namespace 21/74 (microsoft.dynamics365): Found 1 resource actions
VERBOSE: Namespace 22/74 (microsoft.dynamics365.businessCentral): Found 1 resource actions
VERBOSE: Namespace 23/74 (microsoft.edge): Found 2 resource actions
VERBOSE: Namespace 24/74 (microsoft.embeddedFinance.financialConnections): Found 1 resource actions
VERBOSE: Namespace 25/74 (microsoft.networkAccess): Found 3 resource actions
VERBOSE: Namespace 26/74 (microsoft.flow): Found 1 resource actions
VERBOSE: Namespace 27/74 (microsoft.graph.dataConnect): Found 2 resource actions
VERBOSE: Namespace 28/74 (microsoft.hardware.support): Found 7 resource actions
VERBOSE: Namespace 29/74 (microsoft.healthPlatform): Found 2 resource actions
VERBOSE: Namespace 30/74 (microsoft.insights): Found 5 resource actions
VERBOSE: Namespace 31/74 (microsoft.intune): Found 2 resource actions
VERBOSE: Namespace 32/74 (microsoft.managedTenants): Found 1 resource actions
VERBOSE: Namespace 33/74 (microsoft.microsoft365.organizationalData): Found 2 resource actions
VERBOSE: Namespace 34/74 (microsoft.office365.complianceManager): Found 1 resource actions
VERBOSE: Namespace 35/74 (microsoft.office365.desktopAnalytics): Found 1 resource actions
VERBOSE: Namespace 36/74 (microsoft.office365.exchange): Found 4 resource actions
VERBOSE: Namespace 37/74 (microsoft.office365.knowledge): Found 5 resource actions
VERBOSE: Namespace 38/74 (microsoft.office365.lockbox): Found 1 resource actions
VERBOSE: Namespace 39/74 (microsoft.office365.messageCenter): Found 2 resource actions
VERBOSE: Namespace 40/74 (microsoft.office365.network): Found 2 resource actions
VERBOSE: Namespace 41/74 (microsoft.office365.organizationalMessages): Found 3 resource actions
VERBOSE: Namespace 42/74 (microsoft.office365.portalSettings): Found 1 resource actions
VERBOSE: Namespace 43/74 (microsoft.office365.protectionCenter): Found 11 resource actions
VERBOSE: Namespace 44/74 (microsoft.office365.search): Found 2 resource actions
VERBOSE: Namespace 45/74 (microsoft.office365.security): Found 1 resource actions
VERBOSE: Namespace 46/74 (microsoft.office365.securityComplianceCenter): Found 2 resource actions
VERBOSE: Namespace 47/74 (microsoft.office365.serviceHealth): Found 1 resource actions
VERBOSE: Namespace 48/74 (microsoft.office365.sharePoint): Found 1 resource actions
VERBOSE: Namespace 49/74 (microsoft.office365.skypeForBusiness): Found 1 resource actions
VERBOSE: Namespace 50/74 (microsoft.office365.supportTickets): Found 1 resource actions
VERBOSE: Namespace 51/74 (microsoft.office365.usageReports): Found 2 resource actions
VERBOSE: Namespace 52/74 (microsoft.office365.userCommunication): Found 1 resource actions
VERBOSE: Namespace 53/74 (microsoft.office365.webPortal): Found 1 resource actions
VERBOSE: Namespace 54/74 (microsoft.office365.webPortalSettings): Found 1 resource actions
VERBOSE: Namespace 55/74 (microsoft.office365.yammer): Found 2 resource actions
VERBOSE: Namespace 56/74 (microsoft.office365.copilot): Found 2 resource actions
VERBOSE: Namespace 57/74 (microsoft.office365.fileStorageContainers): Found 2 resource actions
VERBOSE: Namespace 58/74 (microsoft.office365.migrations): Found 1 resource actions
VERBOSE: Namespace 59/74 (microsoft.office365.sharePointAdvancedManagement): Found 1 resource actions
VERBOSE: Namespace 60/74 (microsoft.people): Found 4 resource actions
VERBOSE: Namespace 61/74 (microsoft.peopleAdmin): Found 2 resource actions
VERBOSE: Namespace 62/74 (microsoft.permissionsManagement): Found 2 resource actions
VERBOSE: Namespace 63/74 (microsoft.places): Found 1 resource actions
VERBOSE: Namespace 64/74 (microsoft.powerApps): Found 1 resource actions
VERBOSE: Namespace 65/74 (microsoft.powerApps.powerBI): Found 1 resource actions
VERBOSE: Namespace 66/74 (microsoft.purview): Found 1 resource actions
VERBOSE: Namespace 67/74 (microsoft.securityCopilot): Found 1 resource actions
VERBOSE: Namespace 68/74 (microsoft.teams): Found 8 resource actions
VERBOSE: Namespace 69/74 (microsoft.virtualVisits): Found 2 resource actions
VERBOSE: Namespace 70/74 (microsoft.viva.glint): Found 2 resource actions
VERBOSE: Namespace 71/74 (microsoft.viva.goals): Found 2 resource actions
VERBOSE: Namespace 72/74 (microsoft.viva.pulse): Found 2 resource actions
VERBOSE: Namespace 73/74 (microsoft.windows.defenderAdvancedThreatProtection): Found 1 resource actions
VERBOSE: Namespace 74/74 (microsoft.windows.updatesDeployments): Found 2 resource actions
VERBOSE: Total authentication contexts found in protected actions: 0
True

Copy link
Contributor Author

Copilot AI commented Feb 4, 2026

@copilot, all new public functions must be added to the FunctionsToExport value in the module manifest (maester.psd1). The funcion Test-MtCaAuthContextProtectedActionsExist appears to ...

The verbose output shows that the resourceActions objects don't contain an authenticationContextId property. The sample JSON structure shows: id, name, description, isPrivileged, actionVerb, and resourceScopeId - but no authentication context property.

This indicates that authentication context assignments for Protected Actions are stored separately, not as a property on the resource action itself. Based on the Microsoft Graph API structure, Protected Actions with authentication contexts may need to be queried through a different endpoint or via authentication context settings.

Let me investigate the correct API approach. The screenshot shows "c4" as the auth context ID, but it's not appearing in the resourceActions API response, suggesting we need a different query method to retrieve Protected Action-to-authentication-context mappings.

@SamErde SamErde marked this pull request as draft February 4, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request entra Microsoft Entra maester-test Related to a Maester test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants